package msb.class02;


import org.junit.Assert;
import org.junit.Test;
import common.pojo.LinkedNode;
import common.util.ArrayUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 双向链表翻转
 */
public class Code02_ReverseDoubleLinked {

    /**
     * 反转
     *
     * @param head
     * @return
     */
    public static LinkedNode reverse(LinkedNode head) {
        LinkedNode current = head;
        LinkedNode pre = null;
        LinkedNode next;
        while (current != null) {
            next = current.next;
            current.next = pre;
            current.pre = next;
            pre = current;
            current = next;
        }
        return pre;
    }


    /**
     * 创建链表
     */
    public static List<LinkedNode> instance() {
        List<LinkedNode> list = new ArrayList<>();
        int count = 100;
        for (int i = 0; i < count; i++) {
            LinkedNode node = new LinkedNode();
            node.value = ArrayUtil.randomInt(1, 100);
            list.add(node);
        }
        for (int i = 0; i < count; i++) {
            list.get(i).pre = i == 0 ? null : list.get(i - 1);
            list.get(i).next = i == count - 1 ? null : list.get(i + 1);
        }
        return list;
    }

    public void printLinked(LinkedNode head) {
        LinkedNode current = head;
        while (current != null) {
            System.out.print((current.pre == null ? "null" : current.pre.value) + ",");
            System.out.print(current.value + ",");
            System.out.print((current.next == null ? "null" : current.next.value));
            System.out.println();
            current = current.next;
        }
    }

    @Test
    public void testInstance() {
        for (int n = 0; n < 10000; n++) {
            List<LinkedNode> list = instance();
            LinkedNode head = list.get(0);
            List<Integer[]> listO = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                Integer[] nodeValue = new Integer[3];
                LinkedNode node = list.get(i);
                nodeValue[0] = node.pre == null ? null : node.pre.value;
                nodeValue[1] = node.value;
                nodeValue[2] = node.next == null ? null : node.next.value;
                listO.add(nodeValue);
            }
            LinkedNode current = reverse(head);
            for (int i = listO.size() - 1; i >= 0; i--) {
                Integer[] value = listO.get(i);
                Integer next = current.pre == null ? null : current.pre.value;
                Integer cur = current.value;
                Integer pre = current.next == null ? null : current.next.value;
                Assert.assertEquals(value[0], pre);
                Assert.assertEquals(value[1], cur);
                Assert.assertEquals(value[2], next);
                current = current.next;
            }
        }
    }
}

